package mule;

import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.File;
import java.util.ArrayList;
import java.util.logging.Logger;

import javax.sound.sampled.AudioFormat;
import javax.sound.sampled.AudioInputStream;
import javax.sound.sampled.AudioSystem;
import javax.sound.sampled.Clip;
import javax.sound.sampled.DataLine;
import javax.sound.sampled.DataLine.Info;
import javax.swing.*;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;

import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;

/**
 * Class in which the game's main menu options are displayed.
 * 
 */
public class MainMenu extends JFrame {
	JLabel welcome;
	ImageIcon image;
	//stuff for music
	AudioInputStream stream;
	AudioFormat format;
	Info info;
	static Clip clip;

	/**
	 * Constructs a layout for a welcome screen + picture (added later..) and
	 * default options which the player can choose from.
	 */
	public MainMenu() {
		setLayout(new GridLayout(2, 1));
		image = new ImageIcon("src/mule/images/mule.png");
		welcome = new JLabel(image);
		add(welcome);
		add(new Menu());
		setTitle("Mule Main Menu");
		setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE);
		setSize(400, 400);
		setVisible(true);
		setLocationRelativeTo(null);
		setResizable(false);
		try {
		    File yourFile = new File("src/mule/sounds/03-pok-dex.wav");

		    stream = AudioSystem.getAudioInputStream(yourFile);
		    format = stream.getFormat();
		    info = new DataLine.Info(Clip.class, format);
		    clip = (Clip) AudioSystem.getLine(info);
		    clip.open(stream);
		    clip.start();
		}
		catch (Exception e) {
		    e.printStackTrace();
		}
		
	}

	private static Logger myLogger = Logger.getLogger("example.Game");

	/**
	 * The bottom half of the Grid Layout that contains the default options.
	 * 
	 * @author Kevin
	 * 
	 */
	class Menu extends JPanel implements ActionListener {
		String[] levels = { "Beginner", "Intermediate", "Expert" };
		JComboBox levelsList;
		JLabel levelLabel, mapLabel, mapXLabel, mapYLabel, playerLabel;
		JTextField mapX, mapY, players;
		JButton start;
		JButton loadGame;

		public Menu() {
			setLayout(new FlowLayout(FlowLayout.CENTER));
			levelsList = new JComboBox(levels);
			levelLabel = new JLabel("1. Select your difficulty:");
			levelLabel.setPreferredSize(new Dimension(150, 40));
			levelsList.setPreferredSize(new Dimension(180, 25));

			mapLabel = new JLabel("2. Set your map size:");
			mapLabel.setPreferredSize(new Dimension(132, 40));
			mapXLabel = new JLabel("Rows");
			mapYLabel = new JLabel("Columns");
			mapX = new JTextField();
			mapX.setText("5");
			mapY = new JTextField();
			mapY.setText("9");
			mapX.setPreferredSize(new Dimension(50, 25));
			mapY.setPreferredSize(new Dimension(50, 25));

			playerLabel = new JLabel("3. Set the # of players:");
			playerLabel.setPreferredSize(new Dimension(130, 40));
			players = new JTextField();
			players.setPreferredSize(new Dimension(50, 25));

			start = new JButton("Start");
			start.addActionListener(this);
			start.setPreferredSize(new Dimension(200, 30));

			loadGame = new JButton("Load");
			loadGame.addActionListener(this);
			start.setPreferredSize(new Dimension(200, 30));

			add(levelLabel);
			add(levelsList);
			add(mapLabel);
			add(mapXLabel);
			add(mapX);
			add(mapYLabel);
			add(mapY);
			add(playerLabel);
			add(players);
			add(start);
			add(loadGame);
			
			
		}

		/**
		 * Events that occur when the start button is clicked. Will add error
		 * catching from user later. Disposes of the current frame and pops up
		 * with player config screens, then ending with the game screen.
		 */
		@Override
		public void actionPerformed(ActionEvent arg0) {
			if (arg0.getActionCommand().equals("Load")) {
				String gameName = JOptionPane.showInputDialog("Game to load?");
				loadGame(gameName);
				clip.stop();
				dispose();
			} else {
				int level = 0;
				if (levelsList.getSelectedItem().equals("Beginner")) {
					level = 1;
				} else if (levelsList.getSelectedItem().equals("Intermediate")) {
					level = 2;
				} else if (levelsList.getSelectedItem().equals("Expert")) {
					level = 3;
				}
				int x = Integer.parseInt(mapX.getText());
				int y = Integer.parseInt(mapY.getText());
				Map map = new Map(x, y);
				int totalPlayers = Integer.parseInt(players.getText());
				dispose();

				PlayerConfigWindow win = new PlayerConfigWindow(level, map,
						totalPlayers, 0);
			}

		}
	}

	public static Game loadGame(String gameName) {
		Game newGame;
		try {
			Map loadedMap = new Map(5, 9);
			ArrayList<Player> loadedPlayers = new ArrayList<Player>();
			File fXmlFile = new File(gameName + ".xml");
			DocumentBuilderFactory dbFactory = DocumentBuilderFactory
					.newInstance();
			DocumentBuilder dBuilder = dbFactory.newDocumentBuilder();
			Document doc = dBuilder.parse(fXmlFile);

			doc.getDocumentElement().normalize();

			System.out.println("Root element :"
					+ doc.getDocumentElement().getNodeName());

			NodeList nList = doc.getElementsByTagName("Player");

			System.out.println("----------------------------");

			for (int temp = 0; temp < nList.getLength(); temp++) {

				Node nNode = nList.item(temp);

				System.out.println("\nCurrent Element :" + nNode.getNodeName());

				if (nNode.getNodeType() == Node.ELEMENT_NODE) {

					Element eElement = (Element) nNode;

					System.out.println("Player id : "
							+ eElement.getAttribute("id"));
					System.out.println("Name : "
							+ eElement.getElementsByTagName("name").item(0)
									.getTextContent());
					System.out.println("Color : "
							+ eElement.getElementsByTagName("color-red")
									.item(0).getTextContent()
							+ ","
							+ eElement.getElementsByTagName("color-green")
									.item(0).getTextContent()
							+ ","
							+ eElement.getElementsByTagName("color-blue")
									.item(0).getTextContent());
					System.out.println("Score : "
							+ eElement.getElementsByTagName("score").item(0)
									.getTextContent());
					System.out.println("Owned Tiles : "
							+ eElement.getElementsByTagName("tile").item(0)
									.getTextContent());

					int newMoney = Integer.parseInt(eElement
							.getElementsByTagName("money").item(0)
							.getTextContent());
					int newTurnTime = Integer.parseInt(eElement
							.getElementsByTagName("turnTime").item(0)
							.getTextContent());
					int newScore = Integer.parseInt(eElement
							.getElementsByTagName("score").item(0)
							.getTextContent());
					int newFood = Integer.parseInt(eElement
							.getElementsByTagName("food").item(0)
							.getTextContent());
					int newEnergy = Integer.parseInt(eElement
							.getElementsByTagName("energy").item(0)
							.getTextContent());
					int newOre = Integer.parseInt(eElement
							.getElementsByTagName("ore").item(0)
							.getTextContent());
					int newRace = Integer.parseInt(eElement
							.getElementsByTagName("race").item(0)
							.getTextContent());
					int newCrystite = Integer.parseInt(eElement
							.getElementsByTagName("crystite").item(0)
							.getTextContent());

					Color newColor = new Color(Integer.parseInt(eElement
							.getElementsByTagName("color-red").item(0)
							.getTextContent()), Integer.parseInt(eElement
							.getElementsByTagName("color-green").item(0)
							.getTextContent()), Integer.parseInt(eElement
							.getElementsByTagName("color-blue").item(0)
							.getTextContent()));

					ArrayList<Tile> ownedTiles = new ArrayList<Tile>();
					String newName = eElement.getElementsByTagName("name")
							.item(0).getTextContent();
					for (int x = 0; x < eElement.getElementsByTagName("tile")
							.getLength(); x++) {
						Double xc = Double.parseDouble(eElement
								.getElementsByTagName("tile").item(x)
								.getTextContent().substring(0, 2));
						Double yc = Double.parseDouble(eElement
								.getElementsByTagName("tile").item(x)
								.getTextContent().substring(4, 6));
						String myText = eElement.getElementsByTagName("tile")
								.item(x).getTextContent();
						boolean hasMule = false;
						String muleType = "";
						if (!eElement.getElementsByTagName("tile").item(x)
								.getTextContent().substring(8).equals("null")) {
							muleType = eElement.getElementsByTagName("tile")
									.item(x).getTextContent().substring(8);
							System.out.println("mule found: " + muleType);
							hasMule = true;
						}
						int xcint = (int) Math.round(xc);
						int ycint = (int) Math.round(yc);
						Point myPoint = new Point(xcint, ycint);
						if (hasMule) {// fix this
							Map.getTile(myPoint).setMule(new Mule(muleType));
							System.out.println("mule added at"
									+ Map.getTile(myPoint));

						}
						ownedTiles.add(Map.getTile(myPoint));
					}
					Player newPlayer = new Player(newMoney, newTurnTime,
							newScore, newFood, newEnergy, newOre, newRace,
							newCrystite, newColor, newName, ownedTiles);
					loadedPlayers.add(newPlayer);
					for (Tile t : ownedTiles) {
						int idx = (int) (t.getPoint().getY() * 9 + t.getPoint()
								.getX());
						for (JButton jb : Map.getButtons()) {
							if ((int) jb.getClientProperty("number") == idx) {
								jb.setBackground(newPlayer.getColor());
								t.setOwner(newPlayer);
								if (t.hasMule()) {
									System.out.println("got a mule!!!");
									jb.setText("<html><center>" + jb.getText()
											+ ": " + newPlayer.getName()
											+ "'s " + t.getMule()
											+ "</center></html>");
								}
							}

						}
					}
				}
			}
			int difficulty = Integer.parseInt(doc
					.getElementsByTagName("difficulty").item(0)
					.getTextContent());
			int round = Integer.parseInt(doc.getElementsByTagName("round")
					.item(0).getTextContent());
			boolean selection = false;
			if (doc.getElementsByTagName("selection").item(0).getTextContent()
					.equals("true")) {
				selection = true;
			}
			newGame = new Game(selection, difficulty, loadedMap, loadedPlayers,
					round);
			newGame.setVisible(true);
			return newGame;
		} catch (Exception e) {
			e.printStackTrace();
		}
		return null;
	}
}
